home *** CD-ROM | disk | FTP | other *** search
/ MacHack 1994 / MacHack 1994.toast / MacHack™94 / Talks & Papers / Michael D. Crawford↵ / Word Services SDK 1.0.5 / Writeswell Jr. Source / FontMenu.c < prev    next >
Text File  |  1993-03-17  |  9KB  |  392 lines

  1. /* FontMenu.c
  2.  * Handle font and style menus in Writeswell Jr.
  3.  * ©1992 Working Software, Inc.
  4.  * This source code is copyrighted.  Permission is granted to use the Word Services
  5.  * portion of the Writeswell Jr. source code in your own programs, but you 
  6.  * may not distribute the Writeswell Jr. word-processor code as a 
  7.  * commercial product.  If you modify the code, please do not call it 
  8.  * Writeswell Jr. (or Writeswell.)  This will ensure that people understand the 
  9.  * program and don’t have to deal with a number of different versions with 
  10.  * who-knows-what going on in the code.
  11.  * 
  12.  * Writeswell Jr. and Writeswell are trademarks of Working Software, Inc.
  13.  *
  14.  * 19 May 92 Mike Crawford
  15.  */
  16.  
  17. #include <EPPC.h>
  18. #include <AppleEvents.h>
  19. #include <AEObjects.h>
  20. #include <Script.h>
  21. #include "AERegistry.h"
  22. #include "WordServices.h"
  23. #include "TestBed.h"
  24. #include "TBConstants.h"
  25. #include "Gripe.h"
  26. #include "AppEvents.h"
  27. #include "TBGlobals.h"
  28. #include "FontMenu.h"
  29. #include "OutlineButton.h"
  30.  
  31. void FixPasteItem( MenuHandle editMenu );
  32.  
  33. static Style gStyleTable[] = { 0, bold, italic, underline, outline, shadow, condense, extend };
  34. static short gPointSizeTable[] = { 9, 10, 12, 14, 18, 24, 48, 72 };
  35.  
  36. Boolean DoFontMenu( short theItem )
  37. {
  38.     TEHandle    textH;
  39.     TextStyle    styleRec;
  40.     MenuHandle    fontMenu;
  41.     short        fontNum;
  42.     Str255        fontName;
  43.  
  44.     if ( !gDocWindow )
  45.         return true;
  46.         
  47.     textH = (TEHandle)GetWRefCon( gDocWindow );
  48.     
  49.     fontMenu = GetMHandle( kFontMenuID );
  50.     if ( !fontMenu )
  51.         return false;
  52.     
  53.     GetItem( fontMenu, theItem, fontName );
  54.     
  55.     GetFNum( fontName, &fontNum );
  56.     
  57.     /* Set TE to use the new font */
  58.  
  59.     styleRec.tsFont = fontNum;
  60.  
  61.     TESetStyle( doFont, &styleRec, true, textH );
  62.  
  63.     gDocDirty = true;
  64.     
  65.     return true;
  66. }
  67.  
  68. Boolean DoStyleMenu( short theItem )
  69. {
  70.     TEHandle textH;
  71.  
  72.     if ( theItem == kStMOtherPoint ){
  73.         CustomSize();
  74.         return true;
  75.     }
  76.     
  77.     gDocDirty = true;
  78.  
  79.     if ( theItem < kStMDash ){
  80.         SetStyle( theItem );
  81.         return true;
  82.     }
  83.     
  84.     SetSize( theItem );
  85.     
  86.     return true;
  87. }
  88.  
  89. void CustomSize( void )
  90. {
  91.     TextStyle    styleRec;
  92.     short        fontAscent;
  93.     short        lineHeight;
  94.     TEHandle    textH;
  95.     DialogPtr    custDlg;
  96.     short        item;
  97.     Str255        textStr;
  98.     short        kind;
  99.     Handle        h;
  100.     Rect        r;
  101.     long        num;
  102.     
  103.     if ( !gDocWindow )
  104.         return;
  105.         
  106.     textH = (TEHandle)GetWRefCon( gDocWindow );
  107.  
  108.     custDlg = GetNewDialog( kCustomSizeID, (Ptr)NULL, (WindowPtr)-1 );
  109.     if ( !custDlg )
  110.         return;
  111.     
  112.     /* Get the current size */
  113.  
  114.     TEGetStyle( (*textH)->selStart, &styleRec, &lineHeight, &fontAscent, textH );
  115.     NumToString( (long)fontAscent, textStr );
  116.     
  117.     GetDItem( custDlg, kCSEntryField, &kind, &h, &r );
  118.     SetIText( h, textStr );
  119.     
  120.     TESetSelect( 0L, 32000L, ((DialogPeek)custDlg)->textH );
  121.  
  122.     /* Set up a user proc to draw the default outline */
  123.  
  124.     GetDItem( custDlg, kCSDefUser, &kind, &h, &r );
  125.     SetDItem( custDlg, kCSDefUser, kind, (Handle)OutlineButton, &r );
  126.     
  127.     do {
  128.         ModalDialog( (ProcPtr)NULL, &item );
  129.     } while ( item != kCSCancel && item != kCSOK );
  130.     
  131.     if ( item == kCSCancel ){
  132.         DisposDialog( custDlg );
  133.         return;
  134.     }
  135.     
  136.     GetDItem( custDlg, kCSEntryField, &kind, &h, &r );
  137.     GetIText( h, textStr );
  138.     
  139.     DisposDialog( custDlg );
  140.  
  141.     StringToNum( textStr, &num );
  142.     
  143.     /* Set TE to use the new style */
  144.  
  145.     styleRec.tsSize = (short)num;
  146.  
  147.     TESetStyle( doSize, &styleRec, true, textH );
  148.  
  149.     gDocDirty = true;            /* Note that it's not dirty if we canceled */
  150.     
  151.     return;
  152. }
  153.  
  154. void SetStyle( short theItem )
  155. {
  156.     TextStyle    styleRec;
  157.     TEHandle    textH;
  158.  
  159.     if ( !gDocWindow )
  160.         return;
  161.         
  162.     textH = (TEHandle)GetWRefCon( gDocWindow );
  163.     
  164.     /* Set TE to use the new style */
  165.  
  166.     styleRec.tsFace = gStyleTable[ theItem - 1 ];
  167.  
  168.     TESetStyle( doFace, &styleRec, true, textH );
  169.  
  170.     return;
  171. }
  172.  
  173. void SetSize( short theItem )
  174. {
  175.     TextStyle    styleRec;
  176.     TEHandle    textH;
  177.  
  178.     if ( !gDocWindow )
  179.         return;
  180.         
  181.     textH = (TEHandle)GetWRefCon( gDocWindow );
  182.  
  183.     theItem -= kStM9Point;
  184.     
  185.     styleRec.tsSize = gPointSizeTable[ theItem ];
  186.     
  187.     TESetStyle( doSize, &styleRec, true, textH );
  188.     
  189.     return;
  190. }
  191.  
  192. void InitStyleMenu( void )
  193. {
  194.     MenuHandle    styleMenu;
  195.     short        i;
  196.  
  197.     styleMenu = (MenuHandle)GetResource( 'MENU', kStyleMenuID );
  198.     if ( !styleMenu ){
  199.         Gripe( "\pcannot get Style Menu Handle" );
  200.         return;
  201.     }
  202.     
  203.     for ( i = kStMBold; i < kStMDash; i++ ){
  204.         SetItemStyle( styleMenu, i, gStyleTable[ i - 1 ] );
  205.     }
  206.  
  207.     return;
  208. }
  209.  
  210. void FixMenuMarks( void )
  211. {
  212.     TextStyle    styleRec;
  213.     TEHandle    textH;
  214.     MenuHandle    fileMenu;
  215.     MenuHandle    fontMenu;
  216.     MenuHandle    styleMenu;
  217.     MenuHandle    editMenu;
  218.     short        numItems;
  219.     short        i;
  220.     short        fontNum;
  221.     short        itemSize;
  222.     short        lineHeight;
  223.     short        fontAscent;
  224.     Str255        fontName;
  225.     Str255        itemName;
  226.     short        mode;
  227.     Boolean        continuous;
  228.  
  229.     fileMenu = (MenuHandle)GetResource( 'MENU', kFileMenuID );
  230.     if ( !fileMenu )
  231.         return;
  232.  
  233.     editMenu = (MenuHandle)GetResource( 'MENU', kEditMenuID );
  234.     if ( !editMenu )
  235.         return;
  236.  
  237.     fontMenu = (MenuHandle)GetResource( 'MENU', kFontMenuID );
  238.     if ( !fontMenu )
  239.         return;
  240.  
  241.     styleMenu = (MenuHandle)GetResource( 'MENU', kStyleMenuID );
  242.     if ( !styleMenu )
  243.         return;
  244.  
  245.     DisableItem( editMenu, kEMUndo );
  246.  
  247.     if ( !gDocWindow ){
  248.         
  249.         EnableItem( fileMenu, kFMNew );
  250.         EnableItem( fileMenu, kFMOpen );
  251.         DisableItem( fileMenu, kFMClose );
  252.         DisableItem( fileMenu, kFMSave );
  253.         DisableItem( fileMenu, kFMSaveAs );
  254.         DisableItem( fileMenu, kFMPageSetup );
  255.         DisableItem( fileMenu, kFMPrint );
  256.  
  257.         DisableItem( editMenu, kEMPaste );
  258. #ifdef NEVER
  259.         /* STUB Do this differently.  Don't want to redraw menu bar while mouse is down */
  260.         DisableItem( fontMenu, 0 );                /* Disable the entire font menu */
  261.         DisableItem( styleMenu, 0 );            /* Disable the entire style menu */
  262.         DrawMenuBar();
  263. #endif
  264.         return;
  265.     }
  266.  
  267.     SetPort( gDocWindow );
  268.  
  269.     DisableItem( fileMenu, kFMNew );
  270.     DisableItem( fileMenu, kFMOpen );
  271.     EnableItem( fileMenu, kFMClose );
  272.     EnableItem( fileMenu, kFMSave );
  273.     EnableItem( fileMenu, kFMSaveAs );
  274.     EnableItem( fileMenu, kFMPageSetup );
  275.     EnableItem( fileMenu, kFMPrint );
  276.     
  277.     FixPasteItem( editMenu );
  278.  
  279. #ifdef NEVER
  280.     /* STUB Do this differently.  Don't want to redraw menu bar while mouse is down */
  281.     EnableItem( fontMenu, 0 );                /* Enable the entire font menu */
  282.     EnableItem( styleMenu, 0 );                /* Enable the entire style menu */
  283. #endif
  284.     
  285.     textH = (TEHandle)GetWRefCon( gDocWindow );
  286.  
  287.     /* Get the current font */
  288.  
  289. #ifdef NEVER    
  290.     TEGetStyle( (*textH)->selStart, &styleRec, &lineHeight, &fontAscent, textH );
  291. #endif
  292.  
  293.     styleRec.tsFont = 0;
  294.     styleRec.tsSize = 0;
  295.     styleRec.tsFace = 0;
  296.  
  297.     mode = doFont + doFace + doSize;
  298.  
  299.     /* BUG BUG BUG TEContinousStyle does not appear to work as advertised */
  300.     
  301.     continuous = TEContinuousStyle( &mode, &styleRec, textH );
  302.  
  303.     if ( mode & doFont ){
  304.         fontNum = styleRec.tsFont;
  305.         
  306.         if ( fontNum == applFont )
  307.             fontNum = 3 /*GetAppFont()*/;            /* Otherwise Geneva shows up as 1 */
  308.     
  309.         GetFontName( fontNum, fontName );
  310.     }else{
  311.         fontName[ 0 ] = '\0';
  312.     }
  313.  
  314.     numItems = CountMItems( fontMenu );
  315.     
  316.     for ( i = 1; i <= numItems; i++ ){
  317.         GetItem( fontMenu, i, itemName );
  318.         
  319.         if ( PStrCmp( itemName, fontName ) ){
  320.             CheckItem( fontMenu, i, true );
  321.         } else {
  322.             CheckItem( fontMenu, i, false );
  323.         }
  324.     }
  325.     
  326.     /* Show the real font sizes */
  327.     
  328.     for ( i = 0; i < kStMDash2 - kStM9Point; i++ ){
  329.     
  330.         itemSize = gPointSizeTable[ i ];
  331.         
  332.         if ( RealFont( fontNum, itemSize ) ){
  333.             SetItemStyle( styleMenu, i + kStM9Point, outline );
  334.         }else{
  335.             SetItemStyle( styleMenu, i + kStM9Point, 0 );
  336.         }
  337.         
  338.         if ( mode & doSize && itemSize == styleRec.tsSize ){        /* 1.0b2 MDC was fontAscent */
  339.             CheckItem( styleMenu, i + kStM9Point, true );
  340.         } else {
  341.             CheckItem( styleMenu, i + kStM9Point, false );
  342.         }
  343.     }
  344.     
  345.     /* If the styles are the same, check them all, otherwise check none */
  346.     
  347.     for ( i = kStMPlain; i <= kStMExtend; i++ ){
  348.     
  349.         if ( mode & doFace ){
  350.         
  351.             if ( gStyleTable[ i - 1 ] & styleRec.tsFace )
  352.                 CheckItem( styleMenu, i, true );        
  353.         }else{
  354.             CheckItem( styleMenu, i, false );        
  355.         }
  356.     }
  357.      
  358.     return;
  359. }
  360.  
  361. void FixPasteItem( MenuHandle editMenu )
  362. {
  363.     PScrapStuff    scrapPtr;
  364.     long        memFree;
  365.     
  366.     /* It is possible to cause a crash if an application
  367.      * has put a lot on the scrap, even if it is not text.
  368.      * This can happen with Microsoft Word when it puts a
  369.      * huge RTF on the scrap - we crash when we try to paste in
  370.      * the text.  I think this may actually be a bug in System 7.
  371.      * 
  372.      * To prevent this, we disable the paste menu item if
  373.      * there is not enough free memory to hold the whole
  374.      * scrap.  This is not a rigorous test, since FreeMem
  375.      * does not tell how big a single block can be, but it
  376.      * is reasonably fast.
  377.      */
  378.  
  379.      
  380.     memFree = FreeMem();
  381.  
  382.     scrapPtr = InfoScrap();
  383.     
  384.     if ( !scrapPtr || scrapPtr->scrapSize == 0 || scrapPtr->scrapSize > memFree ){
  385.         DisableItem( editMenu, kEMPaste );
  386.         return;
  387.     }
  388.     
  389.     EnableItem( editMenu, kEMPaste );
  390.     
  391.     return;
  392. }